﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Remoting.Messaging;
using System.Windows.Markup;

namespace Liju.Common
{
    /// <summary>
    /// SocketServer
    /// </summary>
    public class SocketServer
    {
        /// <summary>
        /// 缓存接受的数据的byte数组
        /// </summary>
        private static byte[] buffer = new byte[500];
        private static int connectCount = 0;
        public Action<string,string> recAction;
        public List<Socket> clientSockets = new List<Socket>();

        /// <summary>
        /// 开启监听
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void Start(string ip, int port)
        {
            clientSockets.Clear();
            //创建套接字
            IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(ip), port);
            //创建一个新的Tcp协议的Socket对象
            Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //服务器绑定该端口号和ip地址
            Server.Bind(ipEnd);
            //设置该服务器至多只能监听十个客户端
            Server.Listen(10);
            //异步接收客户端
            Server.BeginAccept(new AsyncCallback(ClienAppcet), Server);
        }

        /// <summary>
        /// 监听客户端连接
        /// </summary>
        /// <param name="ar"></param>
        private void ClienAppcet(IAsyncResult ar)
        {
            //每当连接进来的客户端数量增加时链接数量自增1
            connectCount++;
            //服务端对象获取
            Socket ServerSocket = ar.AsyncState as Socket;
            if (ServerSocket != null)
            {
                //得到接受进来的socket客户端
                Socket client = ServerSocket.EndAccept(ar);
                if (!clientSockets.Exists(o => o.RemoteEndPoint == client.RemoteEndPoint))
                {
                    clientSockets.Add(client);
                }
                Console.WriteLine($"客户端连接->{client.RemoteEndPoint}");
                //开始异步接收客户端数据
                client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
                //通过递归来不停的接收客户端的连接
                ServerSocket.BeginAccept(new AsyncCallback(ClienAppcet), ServerSocket);
            }
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveMessage(IAsyncResult ar)
        {
            Socket client = ar.AsyncState as Socket; //客户端对象
            if (client != null)
            {
                IPEndPoint clientipe = (IPEndPoint)client.RemoteEndPoint;
                try
                {
                    int length = client.EndReceive(ar);
                    string message = Encoding.UTF8.GetString(buffer, 0, length);
                    recAction?.Invoke(clientipe.Address.ToString(), message);
                    ////服务器给客户端发送消息表示已经连接上
                    //client.Send(Encoding.UTF8.GetBytes("Server received data"));
                    //通过递归不停的接收该客户端的消息
                    client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
                }
                catch (Exception)
                {
                    //设置计数器
                    connectCount--;
                    //断开连接
                    Console.WriteLine(clientipe + " is disconnected，total connects " + (connectCount), ConsoleColor.Red);
                }
            }
        }

        /// <summary>
        /// 发送接收返回消息
        /// </summary>
        /// <param name="client"></param>
        /// <param name="msg"></param>
        public string SendAddReceive(Socket client, string msg)
        {
            //if (client == null || msg == string.Empty) 
            //    return "" ;

            ////数据转码
            //byte[] data = new byte[1024];
            //data = Encoding.UTF8.GetBytes(msg);
            //try
            //{
            //    //开始发送消息
            //    client.Send(data);
            //    System.Threading.Thread.Sleep(20);

            //    int length = client.Receive(buffer);
            //    string message = Encoding.UTF8.GetString(buffer, 0, length);
            //    return message;

            //}
            //catch (Exception e)
            //{
            //    Console.WriteLine(e.Message);
            //}
            return "";
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="client"></param>
        /// <param name="msg"></param>
        public void AsyncSend(Socket client, string msg)
        {
            if (client == null || msg == string.Empty) return;
            //数据转码
            byte[] data = new byte[100];
            data = Encoding.UTF8.GetBytes(msg);
            try
            {
                //开始发送消息
                client.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
                {
                    //完成消息发送
                    int length = client.EndSend(asyncResult);
                    //输出消息
                    Console.WriteLine(string.Format("发送:{0}", msg));
                }, null);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /// <summary>
        /// 关闭监听服务
        /// </summary>
        public void Close()
        {
            foreach (Socket socket in clientSockets)
            {
                socket.Close();
            }
            clientSockets.Clear();
        }

    }
}
